--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Commit b12860f7d7dedd3463ef1bb988bd6b166128f388
Parents : 2ef0941
Author : Mark Qvist <mark@unsigned.io>
Date : 2024-01-05T18:05:34+01:00
Added multilingual text input options
Changes
10 files changed, 287 insertions(+), 18 deletions(-)
Diff
diff --git a/sbapp/buildozer.spec b/sbapp/buildozer.spec
index 78dd0304..1797ed86 100644
--- a/sbapp/buildozer.spec
+++ b/sbapp/buildozer.spec
@@ -10,7 +10,7 @@ source.exclude_patterns = app_storage/*,venv/*,Makefile,./Makefil*,requirements,
version.regex = __version__ = ['"](.*)['"]
version.filename = %(source.dir)s/main.py
-android.numeric_version = 20240103
+android.numeric_version = 20240105
# Cryptography recipe is currently broken, using RNS-internal crypto for now
requirements = kivy==2.2.1,libbz2,pillow,qrcode==7.3.1,usb4a,usbserial4a
diff --git a/sbapp/main.py b/sbapp/main.py
index dfedba63..a240057d 100644
--- a/sbapp/main.py
+++ b/sbapp/main.py
@@ -69,8 +69,8 @@ if args.daemon:
colors = DaemonElement; Telemeter = DaemonElement; CustomMapMarker = DaemonElement; MBTilesMapSource = DaemonElement;
MapSource = DaemonElement; webbrowser = DaemonElement; Conversations = DaemonElement; MsgSync = DaemonElement;
NewConv = DaemonElement; Telemetry = DaemonElement; ObjectDetails = DaemonElement; Announces = DaemonElement;
- Messages = DaemonElement; ts_format = DaemonElement; messages_screen_kv = DaemonElement; plyer = DaemonElement;
- ContentNavigationDrawer = DaemonElement; DrawerList = DaemonElement; IconListItem = DaemonElement;
+ Messages = DaemonElement; ts_format = DaemonElement; messages_screen_kv = DaemonElement; plyer = DaemonElement; multilingual_markup = DaemonElement;
+ ContentNavigationDrawer = DaemonElement; DrawerList = DaemonElement; IconListItem = DaemonElement; escape_markup = DaemonElement;
else:
from kivymd.app import MDApp
@@ -96,6 +96,7 @@ else:
from mapview import CustomMapMarker
from mapview.mbtsource import MBTilesMapSource
from mapview.source import MapSource
+ from kivy.utils import escape_markup
import webbrowser
import kivy.core.image
kivy.core.image.Logger = redirect_log()
@@ -110,6 +111,7 @@ else:
from ui.announces import Announces
from ui.messages import Messages, ts_format, messages_screen_kv
from ui.helpers import ContentNavigationDrawer, DrawerList, IconListItem
+ from ui.helpers import multilingual_markup
from jnius import cast
from jnius import autoclass
@@ -130,6 +132,7 @@ else:
from .ui.objectdetails import ObjectDetails
from .ui.messages import Messages, ts_format, messages_screen_kv
from .ui.helpers import ContentNavigationDrawer, DrawerList, IconListItem
+ from .ui.helpers import multilingual_markup
from kivy.config import Config
Config.set('input', 'mouse', 'mouse,disable_multitouch')
@@ -180,6 +183,7 @@ class SidebandApp(MDApp):
self.set_ui_theme()
self.font_config()
+ self.update_input_language()
self.dark_theme_text_color = dark_theme_text_color
self.conversations_view = None
@@ -367,7 +371,21 @@ class SidebandApp(MDApp):
LabelBase.register(name="emoji",
fn_regular=fb_path+"NotoEmoji-Regular.ttf")
-
+ LabelBase.register(name="combined",
+ fn_regular=fb_path+"NotoSans-Regular.ttf",
+ fn_bold=fb_path+"NotoSans-Bold.ttf",
+ fn_italic=fb_path+"NotoSans-Italic.ttf",
+ fn_bolditalic=fb_path+"NotoSans-BoldItalic.ttf")
+
+ def update_input_language(self):
+ language = self.sideband.config["input_language"]
+ if language == None:
+ self.input_font = "Roboto"
+ RNS.log("Setting input language to default set", RNS.LOG_DEBUG)
+ else:
+ self.input_font = language
+ RNS.log("Setting input language to "+str(language), RNS.LOG_DEBUG)
+
def update_ui_colors(self):
if self.sideband.config["dark_ui"]:
@@ -1071,7 +1089,8 @@ class SidebandApp(MDApp):
self.messages_view.ids.messages_scrollview.add_widget(list_widget)
self.messages_view.ids.messages_scrollview.scroll_y = 0.0
- self.messages_view.ids.messages_toolbar.title = self.sideband.peer_display_name(context_dest)
+ conv_title = multilingual_markup(escape_markup(str(self.sideband.peer_display_name(context_dest))).encode("utf-8")).decode("utf-8")
+ self.messages_view.ids.messages_toolbar.title = conv_title
self.messages_view.ids.messages_scrollview.active_conversation = context_dest
self.sideband.setstate("app.active_conversation", context_dest)
@@ -1629,6 +1648,8 @@ class SidebandApp(MDApp):
self.settings_screen.ids.settings_scrollview.effect_cls = ScrollEffect
+ self.settings_screen.ids.settings_info_lang.text = "\nIf you write messages in another script than Latin, Greek or Cyrillic, you can configure the text input language for messages and other fields below.\n"
+
info1_text = "\nYou can set your [b]Display Name[/b] to a custom value, or leave it as the default unspecified value. "
info1_text += "This name will be included in any announces you send, and will be visible to others on the network. "
info1_text += "\n\nYou can manually specify which [b]Propagation Node[/b] to use, but if none is specified, Sideband will "
@@ -1676,6 +1697,54 @@ class SidebandApp(MDApp):
self.sideband.config["lxmf_propagation_node"] = new_addr
self.sideband.set_active_propagation_node(self.sideband.config["lxmf_propagation_node"])
+ def save_input_lang(sender=None, event=None):
+ if sender.active:
+ if sender != self.settings_screen.ids.settings_lang_default:
+ self.settings_screen.ids.settings_lang_default.active = False
+
+ if sender != self.settings_screen.ids.settings_lang_chinese:
+ self.settings_screen.ids.settings_lang_chinese.active = False
+
+ if sender != self.settings_screen.ids.settings_lang_japanese:
+ self.settings_screen.ids.settings_lang_japanese.active = False
+
+ if sender != self.settings_screen.ids.settings_lang_korean:
+ self.settings_screen.ids.settings_lang_korean.active = False
+
+ if sender != self.settings_screen.ids.settings_lang_devangari:
+ self.settings_screen.ids.settings_lang_devangari.active = False
+
+ if sender != self.settings_screen.ids.settings_lang_hebrew:
+ self.settings_screen.ids.settings_lang_hebrew.active = False
+
+ RNS.log("Sender: "+str(sender))
+
+ if self.settings_screen.ids.settings_lang_default.active:
+ self.sideband.config["input_language"] = None
+ self.settings_screen.ids.settings_display_name.font_name = ""
+ elif self.settings_screen.ids.settings_lang_chinese.active:
+ self.sideband.config["input_language"] = "chinese"
+ self.settings_screen.ids.settings_display_name.font_name = "chinese"
+ elif self.settings_screen.ids.settings_lang_japanese.active:
+ self.sideband.config["input_language"] = "japanese"
+ self.settings_screen.ids.settings_display_name.font_name = "japanese"
+ elif self.settings_screen.ids.settings_lang_korean.active:
+ self.sideband.config["input_language"] = "korean"
+ self.settings_screen.ids.settings_display_name.font_name = "korean"
+ elif self.settings_screen.ids.settings_lang_devangari.active:
+ self.sideband.config["input_language"] = "combined"
+ self.settings_screen.ids.settings_display_name.font_name = "combined"
+ elif self.settings_screen.ids.settings_lang_hebrew.active:
+ self.sideband.config["input_language"] = "hebrew"
+ self.settings_screen.ids.settings_display_name.font_name = "hebrew"
+ else:
+ self.sideband.config["input_language"] = None
+ self.settings_screen.ids.settings_display_name.font_name = ""
+
+
+ self.sideband.save_configuration()
+ self.update_input_language()
+
def save_dark_ui(sender=None, event=None):
self.sideband.config["dark_ui"] = self.settings_screen.ids.settings_dark_ui.active
self.sideband.save_configuration()
@@ -1840,6 +1909,39 @@ class SidebandApp(MDApp):
self.settings_screen.ids.settings_debug.active = self.sideband.config["debug"]
self.settings_screen.ids.settings_debug.bind(active=save_debug)
+ self.settings_screen.ids.settings_lang_default.active = False
+ self.settings_screen.ids.settings_lang_chinese.active = False
+ self.settings_screen.ids.settings_lang_japanese.active = False
+ self.settings_screen.ids.settings_lang_korean.active = False
+ self.settings_screen.ids.settings_lang_devangari.active = False
+ self.settings_screen.ids.settings_lang_default.bind(active=save_input_lang)
+ self.settings_screen.ids.settings_lang_chinese.bind(active=save_input_lang)
+ self.settings_screen.ids.settings_lang_japanese.bind(active=save_input_lang)
+ self.settings_screen.ids.settings_lang_korean.bind(active=save_input_lang)
+ self.settings_screen.ids.settings_lang_devangari.bind(active=save_input_lang)
+ self.settings_screen.ids.settings_lang_hebrew.bind(active=save_input_lang)
+ input_lang = self.sideband.config["input_language"]
+ if input_lang == None:
+ self.settings_screen.ids.settings_lang_default.active = True
+ self.settings_screen.ids.settings_display_name.font_name = ""
+ elif input_lang == "chinese":
+ self.settings_screen.ids.settings_lang_chinese.active = True
+ self.settings_screen.ids.settings_display_name.font_name = "chinese"
+ elif input_lang == "japanese":
+ self.settings_screen.ids.settings_lang_japanese.active = True
+ self.settings_screen.ids.settings_display_name.font_name = "japanese"
+ elif input_lang == "korean":
+ self.settings_screen.ids.settings_lang_korean.active = True
+ self.settings_screen.ids.settings_display_name.font_name = "korean"
+ elif input_lang == "devangari":
+ self.settings_screen.ids.settings_lang_devangari.active = True
+ self.settings_screen.ids.settings_display_name.font_name = "combined"
+ elif input_lang == "hebrew":
+ self.settings_screen.ids.settings_lang_hebrew.active = True
+ self.settings_screen.ids.settings_display_name.font_name = "hebrew"
+ else:
+ self.settings_screen.ids.settings_display_name.font_name = ""
+
self.settings_ready = True
def close_settings_action(self, sender=None):
diff --git a/sbapp/sideband/core.py b/sbapp/sideband/core.py
index e389f147..5325acab 100644
--- a/sbapp/sideband/core.py
+++ b/sbapp/sideband/core.py
@@ -414,6 +414,11 @@ class SidebandCore():
if not "display_style_in_contact_list" in self.config:
self.config["display_style_in_contact_list"] = False
+ if not "input_language" in self.config:
+ self.config["input_language"] = None
+ if not "allow_predictive_text" in self.config:
+ self.config["allow_predictive_text"] = False
+
if not "connect_transport" in self.config:
self.config["connect_transport"] = False
if not "connect_rnode" in self.config:
diff --git a/sbapp/ui/announces.py b/sbapp/ui/announces.py
index 3f8ee071..d7de0fd9 100644
--- a/sbapp/ui/announces.py
+++ b/sbapp/ui/announces.py
@@ -16,6 +16,12 @@ from kivymd.uix.dialog import MDDialog
from kivy.lang.builder import Builder
+from kivy.utils import escape_markup
+if RNS.vendor.platformutils.get_platform() == "android":
+ from ui.helpers import multilingual_markup
+else:
+ from .helpers import multilingual_markup
+
if RNS.vendor.platformutils.get_platform() == "android":
from ui.helpers import ts_format
else:
@@ -93,9 +99,9 @@ class Announces():
trust_icon = "account-question"
def gen_info(ts, dest, name, dtype):
+ name = multilingual_markup(escape_markup(str(name)).encode("utf-8")).decode("utf-8")
def x(sender):
- yes_button = MDRectangleFlatButton(text="OK",font_size=dp(18))
-
+ yes_button = MDRectangleFlatButton(text="OK",font_size=dp(18))
if dtype == "lxmf.delivery":
ad_text = "[size=22dp]LXMF Peer[/size]\n\nReceived: "+ts+"\nAnnounced Name: "+name+"\nAddress: "+RNS.prettyhexrep(dest)
@@ -118,7 +124,7 @@ class Announces():
time_string = time.strftime(ts_format, time.localtime(ts))
if dest_type == "lxmf.delivery":
- disp_name = self.app.sideband.peer_display_name(context_dest)
+ disp_name = multilingual_markup(escape_markup(str(self.app.sideband.peer_display_name(context_dest))).encode("utf-8")).decode("utf-8")
iconl = IconLeftWidget(icon=trust_icon)
elif dest_type == "lxmf.propagation":
diff --git a/sbapp/ui/conversations.py b/sbapp/ui/conversations.py
index a0822fa6..58bc101d 100644
--- a/sbapp/ui/conversations.py
+++ b/sbapp/ui/conversations.py
@@ -17,6 +17,12 @@ from kivymd.uix.dialog import MDDialog
from kivy.lang.builder import Builder
+from kivy.utils import escape_markup
+if RNS.vendor.platformutils.get_platform() == "android":
+ from ui.helpers import multilingual_markup
+else:
+ from .helpers import multilingual_markup
+
class NewConv(BoxLayout):
pass
@@ -162,9 +168,10 @@ class Conversations():
unread = conv["unread"]
last_activity = conv["last_activity"]
+ peer_disp_name = multilingual_markup(escape_markup(str(self.app.sideband.peer_display_name(context_dest))).encode("utf-8")).decode("utf-8")
if not context_dest in self.added_item_dests:
iconl = self.get_icon(conv)
- item = OneLineAvatarIconListItem(text=self.app.sideband.peer_display_name(context_dest), on_release=self.app.conversation_action)
+ item = OneLineAvatarIconListItem(text=peer_disp_name, on_release=self.app.conversation_action)
item.add_widget(iconl)
item.last_activity = last_activity
item.iconl = iconl
@@ -185,6 +192,11 @@ class Conversations():
yes_button = MDRectangleFlatButton(text="Save",font_size=dp(18), theme_text_color="Custom", line_color=self.app.color_accept, text_color=self.app.color_accept)
no_button = MDRectangleFlatButton(text="Cancel",font_size=dp(18))
dialog_content = ConvSettings(disp_name=disp_name, context_dest=RNS.hexrep(dest, delimit=False), trusted=is_trusted, telemetry=send_telemetry, allow_requests=allow_requests)
+ if self.app.sideband.config["input_language"] != None:
+ dialog_content.ids.name_field.font_name = self.app.sideband.config["input_language"]
+ else:
+ dialog_content.ids.name_field.font_name = ""
+
dialog = MDDialog(
title="Edit Conversation",
text= "With "+RNS.prettyhexrep(dest),
@@ -388,7 +400,6 @@ class Conversations():
else:
for w in self.list.children:
if w.sb_uid == context_dest:
- disp_name = self.app.sideband.peer_display_name(context_dest)
trust_icon = self.trust_icon(conv)
trusted = conv["trust"] == 1
da = self.app.sideband.DEFAULT_APPEARANCE
@@ -410,7 +421,7 @@ class Conversations():
if w.iconl.icon != trust_icon: w.iconl.icon = trust_icon
if w.sb_unread != unread: w.sb_unread = unread
- if w.text != disp_name: w.text = disp_name
+ if w.text != peer_disp_name: w.text = peer_disp_name
self.list.children.sort(key=lambda w: (w.trusted, w.last_activity))
diff --git a/sbapp/ui/helpers.py b/sbapp/ui/helpers.py
index 5957982b..f6a5f121 100644
--- a/sbapp/ui/helpers.py
+++ b/sbapp/ui/helpers.py
@@ -117,6 +117,7 @@ codepoint_map = {
0xa960: [0xa97f, "korean"],
0xac00: [0xd7af, "korean"],
0xd7b0: [0xd7ff, "korean"],
+ 0x0900: [0x097f, "combined"], # Devangari
}
emoji_lookup = ['⌚','⌛','','⏪','⏫','⏬','⏰','⏳','◽','◾','☔','☕','♈','♉','♊','♋','♌','♍','♎','♏','♐','♑','♒','♓','♿','⚓','⚡','⚪','⚫','⚽','⚾','⛄','⛅','⛎','⛔','⛪','⛲','⛳','⛵','⛺','⛽','✅','✊','✋','✨','❌','❎','❓','❔','❕','❗','➕','➖','➗','➰','➿','⬛','⬜','⭐','⭕','🀄','🃏','🆎','🆑','🆒','🆓','🆔','🆕','🆖','🆗','🆘','🆙','🆚','🈁','🈚','🈯','🈲','🈳','🈴','🈵','🈶','🈸','🈹','🈺','🉐','🉑','🌀','🌁','🌂','🌃','🌄','🌅','🌆','🌇','🌈','🌉','🌊','🌋','🌌','🌍','🌎','🌏','🌐','🌑','🌒','🌓','🌔','🌕','🌖','🌗','🌘','🌙','🌚','🌛','🌜','🌝','🌞','🌟','🌠','🌭','🌮','🌯','🌰','🌱','🌲','🌳','🌴','🌵','🌷','🌸','🌹','🌺','🌻','🌼','🌽','🌾','🌿','🍀','🍁','🍂','🍃','🍄','🍅','🍆','🍇','🍈','🍉','🍊','🍋','🍌','🍍','🍎','🍏','🍐','🍑','🍒','🍓','🍔','🍕','🍖','🍗','🍘','🍙','🍚','🍛','🍜','🍝','🍞','🍟','🍠','🍡','🍢','🍣','🍤','🍥','🍦','🍧','🍨','🍩','🍪','🍫','🍬','🍭','🍮','🍯','🍰','🍱','🍲','🍳','🍴','🍵','🍶','🍷','🍸','🍹','🍺','🍻','🍼','🍾','🍿','🎀','🎁','🎂','🎃','🎄','🎅','🎆','🎇','🎈','🎉','🎊','🎋','🎌','🎍','🎎','🎏','🎐','🎑','🎒','🎓','🎠','🎡','🎢','🎣','🎤','🎥','🎦','🎧','🎨','🎩','🎪','🎫','🎬','🎭','🎮','🎯','🎰','🎱','🎲','🎳','🎴','🎵','🎶','🎷','🎸','🎹','🎺','🎻','🎼','🎽','🎾','🎿','🏀','🏁','🏂','🏃','🏄','🏅','🏆','🏇','🏈','🏉','🏊','🏏','🏐','🏑','🏒','🏓','🏠','🏡','🏢','🏣','🏤','🏥','🏦','🏧','🏨','🏩','🏪','🏫','🏬','🏭','🏮','🏯','🏰','🏴','🏸','🏹','🏺','🏻','🏼','🏽','🏾','🏿','🐀','🐁','🐂','🐃','🐄','🐅','🐆','🐇','🐈','🐉','🐊','🐋','🐌','🐍','🐎','🐏','🐐','🐑','🐒','🐓','🐔','🐕','🐖','🐗','🐘','🐙','🐚','🐛','🐜','🐝','🐞','🐟','🐠','🐡','🐢','🐣','🐤','🐥','🐦','🐧','🐨','🐩','🐪','🐫','🐬','🐭','🐮','🐯','🐰','🐱','🐲','🐳','🐴','🐵','🐶','🐷','🐸','🐹','🐺','🐻','🐼','🐽','🐾','👀','👂','👃','👄','👅','👆','👇','👈','👉','👊','👋','👌','👍','👎','👏','👐','👑','👒','👓','👔','👕','👖','👗','👘','👙','👚','👛','👜','👝','👞','👟','👠','👡','👢','👣','👤','👥','👦','👧','👨','👩','👪','👫','👬','👭','👮','👯','👰','👱','👲','👳','👴','👵','👶','👷','👸','👹','👺','👻','👼','👽','👾','👿','💀','💁','💂','💃','💄','💅','💆','💇','💈','💉','💊','💋','💌','💍','💎','💏','💐','💑','💒','💓','💔','💕','💖','💗','💘','💙','💚','💛','💜','💝','💞','💟','💠','💡','💢','💣','💤','💥','💦','💧','💨','💩','💪','💫','💬','💭','💮','💯','💰','💱','💲','💳','💴','💵','💶','💷','💸','💹','💺','💻','💼','💽','💾','💿','📀','📁','📂','📃','📄','📅','📆','📇','📈','📉','📊','📋','📌','📍','📎','📏','📐','📑','📒','📓','📔','📕','📖','📗','📘','📙','📚','📛','📜','📝','📞','📟','📠','📡','📢','📣','📤','📥','📦','📧','📨','📩','📪','📫','📬','📭','📮','📯','📰','📱','📲','📳','📴','📵','📶','📷','📸','📹','📺','📻','📼','📿','🔀','🔁','🔂','🔃','🔄','🔅','🔆','🔇','🔈','🔉','🔊','🔋','🔌','🔍','🔎','🔏','🔐','🔑','🔒','🔓','🔔','🔕','🔖','🔗','🔘','🔙','🔚','🔛','🔜','🔝','🔞','🔟','🔠','🔡','🔢','🔣','🔤','🔥','🔦','🔧','🔨','🔩','🔪','🔫','🔬','🔭','🔮','🔯','🔰','🔱','🔲','🔳','🔴','🔵','🔶','🔷','🔸','🔹','🔺','🔻','🔼','🔽','🕋','🕌','🕍','🕎','🕐','🕑','🕒','🕓','🕔','🕕','🕖','🕗','🕘','🕙','🕚','🕛','🕜','🕝','🕞','🕟','🕠','🕡','🕢','🕣','🕤','🕥','🕦','🕧','🖕','🖖','🗻','🗼','🗽','🗾','🗿','😀','😁','😂','😃','😄','😅','😆','😇','😈','😉','😊','😋','😌','😍','😎','😏','😐','😑','😒','😓','😔','😕','😖','😗','😘','😙','😚','😛','😜','😝','😞','😟','😠','😡','😢','😣','😤','😥','😦','😧','😨','😩','😪','😫','😬','😭','😮','😯','😰','😱','😲','😳','😴','😵','😶','😷','😸','😹','😺','😻','😼','😽','😾','😿','🙀','🙁','🙂','🙃','🙄','🙅','🙆','🙇','🙈','🙉','🙊','🙋','🙌','🙍','🙎','🙏','🚀','🚁','🚂','🚃','🚄','🚅','🚆','🚇','🚈','🚉','🚊','🚋','🚌','🚍','🚎','🚏','🚐','🚑','🚒','🚓','🚔','🚕','🚖','🚗','🚘','🚙','🚚','🚛','🚜','🚝','🚞','🚟','🚠','🚡','🚢','🚣','🚤','🚥','🚦','🚧','🚨','🚩','🚪','🚫','🚬','🚭','🚮','🚯','🚰','🚱','🚲','🚳','🚴','🚵','🚶','🚷','🚸','🚹','🚺','🚻','🚼','🚽','🚾','🚿','🛀','🛁','🛂','🛃','🛄','🛅','🛌','🛐','🛫','🛬','🤐','🤑','🤒','🤓','🤔','🤕','🤖','🤗','🤘','🦀','🦁','🦂','🦃','🦄','🧀','🇦🇨','🇦🇩','🇦🇪','🇦🇫','🇦🇬','🇦🇮','🇦🇱','🇦🇲','🇦🇴','🇦🇶','🇦🇷','🇦🇸','🇦🇹','🇦🇺','🇦🇼','🇦🇽','🇦🇿','🇧🇦','🇧🇧','🇧🇩','🇧🇪','🇧🇫','🇧🇬','🇧🇭','🇧🇮','🇧🇯','🇧🇱','🇧🇲','🇧🇳','🇧🇴','🇧🇶','🇧🇷','🇧🇸','🇧🇹','🇧🇻','🇧🇼','🇧🇾','🇧🇿','🇨🇦','🇨🇨','🇨🇩','🇨🇫','🇨🇬','🇨🇭','🇨🇮','🇨🇰','🇨🇱','🇨🇲','🇨🇳','🇨🇴','🇨🇵','🇨🇷','🇨🇺','🇨🇻','🇨🇼','🇨🇽','🇨🇾','🇨🇿','🇩🇪','🇩🇬','🇩🇯','🇩🇰','🇩🇲','🇩🇴','🇩🇿','🇪🇦','🇪🇨','🇪🇪','🇪🇬','🇪🇭','🇪🇷','🇪🇸','🇪🇹','🇪🇺','🇫🇮','🇫🇯','🇫🇰','🇫🇲','🇫🇴','🇫🇷','🇬🇦','🇬🇧','🇬🇩','🇬🇪','🇬🇫','🇬🇬','🇬🇭','🇬🇮','🇬🇱','🇬🇲','🇬🇳','🇬🇵','🇬🇶','🇬🇷','🇬🇸','🇬🇹','🇬🇺','🇬🇼','🇬🇾','🇭🇰','🇭🇲','🇭🇳','🇭🇷','🇭🇹','🇭🇺','🇮🇨','🇮🇩','🇮🇪','🇮🇱','🇮🇲','🇮🇳','🇮🇴','🇮🇶','🇮🇷','🇮🇸','🇮🇹','🇯🇪','🇯🇲','🇯🇴','🇯🇵','🇰🇪','🇰🇬','🇰🇭','🇰🇮','🇰🇲','🇰🇳','🇰🇵','🇰🇷','🇰🇼','🇰🇾','🇰🇿','🇱🇦','🇱🇧','🇱🇨','🇱🇮','🇱🇰','🇱🇷','🇱🇸','🇱🇹','🇱🇺','🇱🇻','🇱🇾','🇲🇦','🇲🇨','🇲🇩','🇲🇪','🇲🇫','🇲🇬','🇲🇭','🇲🇰','🇲🇱','🇲🇲','🇲🇳','🇲🇴','🇲🇵','🇲🇶','🇲🇷','🇲🇸','🇲🇹','🇲🇺','🇲🇻','🇲🇼','🇲🇽','🇲🇾','🇲🇿','🇳🇦','🇳🇨','🇳🇪','🇳🇫','🇳🇬','🇳🇮','🇳🇱','🇳🇴','🇳🇵','🇳🇷','🇳🇺','🇳🇿','🇴🇲','🇵🇦','🇵🇪','🇵🇫','🇵🇬','🇵🇭','🇵🇰','🇵🇱','🇵🇲','🇵🇳','🇵🇷','🇵🇸','🇵🇹','🇵🇼','🇵🇾','🇶🇦','🇷🇪','🇷🇴','🇷🇸','🇷🇺','🇷🇼','🇸🇦','🇸🇧','🇸🇨','🇸🇩','🇸🇪','🇸🇬','🇸🇭','🇸🇮','🇸🇯','🇸🇰','🇸🇱','🇸🇲','🇸🇳','🇸🇴','🇸🇷','🇸🇸','🇸🇹','🇸🇻','🇸🇽','🇸🇾','🇸🇿','🇹🇦','🇹🇨','🇹🇩','🇹🇫','🇹🇬','🇹🇭','🇹🇯','🇹🇰','🇹🇱','🇹🇲','🇹🇳','🇹🇴','🇹🇷','🇹🇹','🇹🇻','🇹🇼','🇹🇿','🇺🇦','🇺🇬','🇺🇲','🇺🇸','🇺🇾','🇺🇿','🇻🇦','🇻🇨','🇻🇪','🇻🇬','🇻🇮','🇻🇳','🇻🇺','🇼🇫','🇼🇸','🇽🇰','🇾🇪','🇾🇹','🇿🇦','🇿🇲','🇿🇼'];
\ No newline at end of file
diff --git a/sbapp/ui/layouts.py b/sbapp/ui/layouts.py
index 6bed4463..b2de6e69 100644
--- a/sbapp/ui/layouts.py
+++ b/sbapp/ui/layouts.py
@@ -1438,8 +1438,8 @@ MDScreen:
MDBoxLayout:
orientation: "horizontal"
size_hint_y: None
- padding: [0,0,dp(24),dp(0)]
- height: dp(48)
+ padding: [0,0,dp(24),dp(24)]
+ height: dp(48+24)
MDLabel:
text: "Debug Logging"
@@ -1450,6 +1450,141 @@ MDScreen:
pos_hint: {"center_y": 0.3}
disabled: False
active: False
+
+ MDLabel:
+ text: "Input Options & Localisation"
+ font_style: "H6"
+ size_hint_y: None
+ height: self.texture_size[1]
+
+ MDLabel:
+ id: settings_info_lang
+ markup: True
+ text: ""
+ size_hint_y: None
+ height: self.texture_size[1]
+
+ MDBoxLayout:
+ orientation: "horizontal"
+ size_hint_y: None
+ padding: [0,0,dp(24),dp(0)]
+ height: dp(48)
+
+ MDLabel:
+ text: "Latin, Greek, Cyrillic"
+ font_style: "H6"
+
+ MDSwitch:
+ id: settings_lang_default
+ pos_hint: {"center_y": 0.3}
+ active: False
+
+ MDBoxLayout:
+ orientation: "horizontal"
+ size_hint_y: None
+ padding: [0,0,dp(24),dp(0)]
+ height: dp(48)
+
+ MDLabel:
+ text: "Chinese"
+ font_style: "H6"
+
+ MDSwitch:
+ id: settings_lang_chinese
+ pos_hint: {"center_y": 0.3}
+ active: False
+
+ MDBoxLayout:
+ orientation: "horizontal"
+ size_hint_y: None
+ padding: [0,0,dp(24),dp(0)]
+ height: dp(48)
+
+ MDLabel:
+ text: "Japanese"
+ font_style: "H6"
+
+ MDSwitch:
+ id: settings_lang_japanese
+ pos_hint: {"center_y": 0.3}
+ active: False
+
+ MDBoxLayout:
+ orientation: "horizontal"
+ size_hint_y: None
+ padding: [0,0,dp(24),dp(0)]
+ height: dp(48)
+
+ MDLabel:
+ text: "Korean"
+ font_style: "H6"
+
+ MDSwitch:
+ id: settings_lang_korean
+ pos_hint: {"center_y": 0.3}
+ active: False
+
+ MDBoxLayout:
+ orientation: "horizontal"
+ size_hint_y: None
+ padding: [0,0,dp(24),dp(0)]
+ height: dp(48)
+
+ MDLabel:
+ text: "Devangari"
+ font_style: "H6"
+
+ MDSwitch:
+ id: settings_lang_devangari
+ pos_hint: {"center_y": 0.3}
+ active: False
+
+ MDBoxLayout:
+ orientation: "horizontal"
+ size_hint_y: None
+ padding: [0,0,dp(24),dp(0)]
+ height: dp(48)
+
+ MDLabel:
+ text: "Hebrew (incomplete)"
+ font_style: "H6"
+
+ MDSwitch:
+ id: settings_lang_hebrew
+ pos_hint: {"center_y": 0.3}
+ active: False
+
+ # MDBoxLayout:
+ # orientation: "horizontal"
+ # size_hint_y: None
+ # padding: [0,0,dp(24),dp(0)]
+ # height: dp(48)
+
+ # MDLabel:
+ # text: "Allow Predictive Text"
+ # font_style: "H6"
+
+ # MDSwitch:
+ # id: settings_allow_predictive_text
+ # pos_hint: {"center_y": 0.3}
+ # active: False
+
+ # MDBoxLayout:
+ # orientation: "vertical"
+ # size_hint_y: None
+ # height: self.minimum_height
+ # padding: [0, dp(24), 0, dp(24)]
+
+ # MDRectangleFlatIconButton:
+ # id: hardware_rnode_button
+ # icon: "translate"
+ # text: "Input Languages"
+ # padding: [dp(0), dp(14), dp(0), dp(14)]
+ # icon_size: dp(24)
+ # font_size: dp(16)
+ # size_hint: [1.0, None]
+ # on_release: root.app.input_languages_action(self)
+
"""
layout_repository_screen = """
diff --git a/sbapp/ui/messages.py b/sbapp/ui/messages.py
index b5f7a87f..6e7d2d02 100644
--- a/sbapp/ui/messages.py
+++ b/sbapp/ui/messages.py
@@ -176,6 +176,8 @@ class Messages():
intensity_msgs = intensity_msgs_light
mt_color = [1.0, 1.0, 1.0, 0.95]
+ self.ids.message_text.font_name = self.app.input_font
+
if self.loading_earlier_messages:
self.new_messages.reverse()
diff --git a/sbapp/ui/objectdetails.py b/sbapp/ui/objectdetails.py
index 2ac773d4..f208464d 100644
--- a/sbapp/ui/objectdetails.py
+++ b/sbapp/ui/objectdetails.py
@@ -20,6 +20,11 @@ from kivymd.toast import toast
from datetime import datetime
+from kivy.utils import escape_markup
+if RNS.vendor.platformutils.get_platform() == "android":
+ from ui.helpers import multilingual_markup
+else:
+ from .helpers import multilingual_markup
if RNS.vendor.platformutils.get_platform() == "android":
from ui.helpers import ts_format
@@ -138,7 +143,7 @@ class ObjectDetails():
self.coords = None
self.telemetry_list.data = []
- pds = self.app.sideband.peer_display_name(source_dest)
+ pds = multilingual_markup(escape_markup(str(self.app.sideband.peer_display_name(source_dest))).encode("utf-8")).decode("utf-8")
appearance = self.app.sideband.peer_appearance(source_dest)
self.screen.ids.name_label.text = pds
@@ -330,7 +335,7 @@ class RVDetails(MDRecycleView):
Clipboard.copy(istr)
toast("Copied to clipboard")
release_function = copy_info
- external_text = escape_markup(istr)
+ external_text = multilingual_markup(escape_markup(istr).encode("utf-8")).decode("utf-8")
formatted_values = f"[b]Information[/b]: {external_text}"
elif name == "Received":
formatted_values = ""
diff --git a/sbapp/ui/telemetry.py b/sbapp/ui/telemetry.py
index df78cce1..209edd8a 100644
--- a/sbapp/ui/telemetry.py
+++ b/sbapp/ui/telemetry.py
@@ -15,11 +15,8 @@ from kivy.effects.scroll import ScrollEffect
from kivy.clock import Clock
from sideband.sense import Telemeter
import threading
-
-
from datetime import datetime
-
if RNS.vendor.platformutils.get_platform() == "android":
from ui.helpers import ts_format
from android.permissions import request_permissions, check_permission
@@ -374,6 +371,11 @@ class Telemetry():
self.sensors_screen.ids.telemetry_s_information_text.text = str(self.app.sideband.config["telemetry_s_information_text"])
self.sensors_screen.ids.telemetry_s_information_text.bind(focus=self.sensors_save)
+ if self.app.sideband.config["input_language"] != None:
+ self.sensors_screen.ids.telemetry_s_information_text.font_name = self.app.sideband.config["input_language"]
+ else:
+ self.sensors_screen.ids.telemetry_s_information_text.font_name = ""
+
def sensors_open(self, sender=None, direction="left", no_transition=False):
if no_transition:
self.app.root.ids.screen_manager.transition = self.app.no_transition
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────